/*
    独立测试套件的使用

    全局测试套件和独立套件的区别：
        1. 全局测试套件在所有的测试函数执行前，会进行初始化，在测试结束后，进行清理，通过SetUp和TearDown来完成
        2. 独立测试套件在所有相关的(使用独立测试环境类名作为测试函数的测试套件名)测试函数执行前，会进行初始化，在测试结束后，进行清理，通过SetUpTestCase和TearDownTestCase来完成
        3. 独立测试套件也可以在每一个的相关的测试函数执行前，会进行初始化，在测试结束后，进行清理，通过SetUp和TearDown来完成
        4. 独立测试套件的成员变量的在测试函数中的操作是独立的，每个相关的测试函数之间数据互不影响
*/
#include <iostream>
#include <vector>
#include "gtest/gtest.h"

// 独立测试环境类
// 用独立测试环境类名作为测试套件名的所有测试函数TEST_F，在其测试前会对数据进行统一初始化，在测试结束后会对数据统一进行清理
std::vector<int> global_vector;
class SuitEnvironment : public testing::Test
{
public:
    virtual void SetUp() override // 在每一个相关的测试函数执行前，进行数据的初始化
    {
        std::cout << "SuitEnvironment: 独立测试环境初始化..." << std::endl;
        _vector.push_back(1);
    }

    virtual void TearDown() override // 在每一个相关的测试函数执行后，进行数据的清理
    {
        std::cout << "SuitEnvironment: 独立测试环境清理..." << std::endl;
        _vector.clear();
    }

    // 在全局测试套件中SetUpTestCase和TearDownTestCase是不生效的
    static void SetUpTestCase() // 在所有相关的测试函数执行前，进行数据的初始化
    {
        std::cout << "SuitEnvironment: 测试环境初始化..." << std::endl;
    }

    static void TearDownTestCase() // 在所有相关的测试函数执行后，进行数据的清理
    {
        std::cout << "SuitEnvironment: 测试环境清理..." << std::endl;
    }

public:
    // 对于相关的测试函数来说，局部成员变量是独立的(每个测试函数中对成员变量的修改是不影响的)
    // 但是如果在初始化函数中对成员变量修改，在其相关的测试函数中是共享的
    std::vector<int> _vector;
};

// 第一个参数必须是继承自testing::Test的类名
// TEST_F会创建一个继承自指定类的子类，测试用例函数成为该子类的成员函数，这样可以直接访问测试类的成员变量和方法
TEST_F(SuitEnvironment, Test1)
{
    std::cout << "SuitEnvironment: 测试全局数据开始..." << std::endl;
    global_vector.push_back(1);
    global_vector.push_back(2);
    EXPECT_EQ(global_vector.size(), 2);
    std::cout << "SuitEnvironment: 测试全局数据结束..." << std::endl;
}

TEST_F(SuitEnvironment, Test2)
{
    std::cout << "SuitEnvironment: 测试全局数据开始..." << std::endl;
    global_vector.push_back(1);
    global_vector.push_back(2);
    EXPECT_EQ(global_vector.size(), 2);
    std::cout << "SuitEnvironment: 测试全局数据结束..." << std::endl;
}

TEST_F(SuitEnvironment, Test3)
{
    std::cout << "SuitEnvironment: 测试局部数据开始..." << std::endl;
    _vector.push_back(1); // 局部成员变量的操作在测试函数中是独立的
    _vector.push_back(2);
    ASSERT_EQ(_vector.size(), 3);
    std::cout << "SuitEnvironment: 测试局部数据结束..." << std::endl;
}

TEST_F(SuitEnvironment, Test4)
{
    std::cout << "SuitEnvironment: 测试局部数据开始..." << std::endl;
    _vector.push_back(1); // 局部成员变量的操作在测试函数中是独立的
    _vector.push_back(2);
    ASSERT_EQ(_vector.size(), 3);
    std::cout << "SuitEnvironment: 测试局部数据结束..." << std::endl;
}

int main(int argc, char* argv[]) 
{
    testing::InitGoogleTest(&argc, argv);
    RUN_ALL_TESTS();
    return 0;
}